<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="laravel-的任务调度-计划任务-功能-task-scheduling" tabindex="-1"><a class="header-anchor" href="#laravel-的任务调度-计划任务-功能-task-scheduling"><span>Laravel 的任务调度（计划任务）功能 Task Scheduling</span></a></h2>
<ul>
<li>
<p><a href="#introduction">简介</a></p>
</li>
<li>
<p><a href="#defining-schedules">定义调度</a></p>
<ul>
<li><a href="#scheduling-artisan-commands">Artisan 命令调度</a></li>
<li><a href="#scheduling-queued-jobs">队列任务调度</a></li>
<li><a href="#scheduling-shell-commands">Shell 调度命令</a></li>
<li><a href="#schedule-frequency-options">调度频率设置</a></li>
<li><a href="#preventing-task-overlaps">避免任务重复</a></li>
<li><a href="#maintenance-mode">维护模式</a></li>
</ul>
</li>
<li>
<p><a href="#task-output">任务输出</a></p>
</li>
<li>
<p><a href="#task-hooks">任务钩子</a></p>
</li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>在过去，开发者必须在服务器上为每个任务生成单独的 Cron 项目。而令人头疼的是任务调度不受源代码控制，而且必须通过 SSH 连接到服务器上来增加 Cron 项目。</p>
<p>Laravel 的命令调度程序允许你在 Laravel 中对命令调度进行清晰流畅的定义。并且在使用调度程序时，只需要在服务器上增加一条 Cron 项目即可。调度是在 <code v-pre>app/Console/Kernel.php</code> 文件的 <code v-pre>schedule</code> 方法中定义的。为了方便你开始，该方法已经包含了一个简单的例子。</p>
<h3 id="启动调度器" tabindex="-1"><a class="header-anchor" href="#启动调度器"><span>启动调度器</span></a></h3>
<p>使用调度器时，只需将以下 Cron 项目添加到服务器。如果你不知道如何将 Cron 项目添加到服务器，可以考虑使用 <a href="https://forge.laravel.com/" target="_blank" rel="noopener noreferrer">Laravel Forge</a> 等服务来管理你的 Cron 项目：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token operator">*</span> <span class="token operator">*</span> <span class="token operator">*</span> <span class="token operator">*</span> <span class="token operator">*</span> php <span class="token operator">/</span>path<span class="token operator">-</span>to<span class="token operator">-</span>your<span class="token operator">-</span>project<span class="token operator">/</span>artisan schedule<span class="token punctuation">:</span>run <span class="token operator">>></span> <span class="token operator">/</span>dev<span class="token operator">/</span><span class="token constant">null</span> <span class="token number">2</span><span class="token operator">></span><span class="token operator">&amp;</span><span class="token number">1</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>上面这个 Cron 会每分钟调用一次 Laravel 命令调度器。执行 <code v-pre>schedule:run</code> 命令时， Laravel 会根据你的调度运行预定任务。</p>
<h2 id="定义调度" tabindex="-1"><a class="header-anchor" href="#定义调度"><span>定义调度</span></a></h2>
<p>你可以在 <code v-pre>App\Console\Kernel</code> 类的 <code v-pre>schedule</code> 方法中定义所有调度任务。在开始之前，先看看一个调度任务的例子。在该例子中，我们将计划在每天午夜调用一个 <code v-pre>Closure</code>。在这个 <code v-pre>Closure</code> 中，将执行一个数据库查询来清除一个表：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Console</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">DB</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Console<span class="token punctuation">\</span>Scheduling<span class="token punctuation">\</span>Schedule</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Console<span class="token punctuation">\</span>Kernel</span> <span class="token keyword">as</span> ConsoleKernel<span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Kernel</span> <span class="token keyword">extends</span> <span class="token class-name">ConsoleKernel</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 应用提供的 Artisan 命令</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@var</span> <span class="token class-name"><span class="token keyword">array</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token variable">$commands</span> <span class="token operator">=</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name class-name-fully-qualified static-context"><span class="token punctuation">\</span>App<span class="token punctuation">\</span>Console<span class="token punctuation">\</span>Commands<span class="token punctuation">\</span>Inspire</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 定义应用的命令调度</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@param</span>  <span class="token class-name"><span class="token punctuation">\</span>Illuminate<span class="token punctuation">\</span>Console<span class="token punctuation">\</span>Scheduling<span class="token punctuation">\</span>Schedule</span>  <span class="token parameter">$schedule</span></span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">schedule</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Schedule</span> <span class="token variable">$schedule</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'recent_users'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="artisan-命令调度" tabindex="-1"><a class="header-anchor" href="#artisan-命令调度"><span>Artisan 命令调度</span></a></h3>
<p>除了计划 <code v-pre>Closure</code> 调用，你还能调度 <a href="https://learnku.com/docs/laravel/5.5/artisan" target="_blank" rel="noopener noreferrer">Artisan 命令</a> 和操作系统命令。举个例子，你可以给 <code v-pre>command</code> 方法传递命令名称或者类名称来调度一个 <code v-pre>Artisan</code> 命令：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'emails:send --force'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token class-name static-context">EmailsCommand</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'--force'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="队列任务调度" tabindex="-1"><a class="header-anchor" href="#队列任务调度"><span>队列任务调度</span></a></h3>
<p><code v-pre>job</code> 方法可以用来调度 <a href="https://learnku.com/docs/laravel/5.5/queues" target="_blank" rel="noopener noreferrer">队列任务</a>。这个方法提供了一种快捷方式来调度任务，无需使用 <code v-pre>call</code> 方法手动创建闭包来调度任务：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">job</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Heartbeat</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">everyFiveMinutes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="shell-命令调度" tabindex="-1"><a class="header-anchor" href="#shell-命令调度"><span>Shell 命令调度</span></a></h3>
<p><code v-pre>exec</code> 方法可用于向操作系统发出命令：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">exec</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'node /home/forge/script.js'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="调度频率设置" tabindex="-1"><a class="header-anchor" href="#调度频率设置"><span>调度频率设置</span></a></h3>
<p>当然，你可以为你的任务分配多种调度计划：</p>
<table>
<thead>
<tr>
<th>方法</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code v-pre>-&gt;cron('* * * * *');</code></td>
<td>在自定义的 Cron 时间表上执行该任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;everyMinute();</code></td>
<td>每分钟执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;everyFiveMinutes();</code></td>
<td>每五分钟执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;everyTenMinutes();</code></td>
<td>每十分钟执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;everyFifteenMinutes();</code></td>
<td>每十五分钟执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;everyThirtyMinutes();</code></td>
<td>每半小时执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;hourly();</code></td>
<td>每小时执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;hourlyAt(17);</code></td>
<td>每小时的第 17 分钟执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;daily();</code></td>
<td>每天午夜执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;dailyAt('13:00');</code></td>
<td>每天的 13:00 执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;twiceDaily(1, 13);</code></td>
<td>每天的 1:00 和 13:00 分别执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;weekly();</code></td>
<td>每周执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;monthly();</code></td>
<td>每月执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;monthlyOn(4, '15:00');</code></td>
<td>在每个月的第四天的 15:00 执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;quarterly();</code></td>
<td>每季度执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;yearly();</code></td>
<td>每年执行一次任务</td>
</tr>
<tr>
<td><code v-pre>-&gt;timezone('America/New_York');</code></td>
<td>设置时区</td>
</tr>
</tbody>
</table>
<p>这些方法可以合并其它限制条件以生成更精确的调度。例如，计划每周周一的调度：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// 每周一的下午一点钟运行</span></span>
<span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">//</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">weekly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">mondays</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">at</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'13:00'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 周一至周五上午 8 点至下午 5 点每小时运行一次...</span></span>
<span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'foo'</span><span class="token punctuation">)</span></span>
<span class="line">          <span class="token operator">-></span><span class="token function">weekdays</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">          <span class="token operator">-></span><span class="token function">hourly</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">          <span class="token operator">-></span><span class="token function">timezone</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'America/Chicago'</span><span class="token punctuation">)</span></span>
<span class="line">          <span class="token operator">-></span><span class="token function">between</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'8:00'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'17:00'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>以下是额外限制条件的列表：</p>
<table>
<thead>
<tr>
<th>方法</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code v-pre>-&gt;weekdays();</code></td>
<td>将任务限制在工作日</td>
</tr>
<tr>
<td><code v-pre>-&gt;sundays();</code></td>
<td>将任务限制在星期天</td>
</tr>
<tr>
<td><code v-pre>-&gt;mondays();</code></td>
<td>将任务限制在星期一</td>
</tr>
<tr>
<td><code v-pre>-&gt;tuesdays();</code></td>
<td>将任务限制在星期二</td>
</tr>
<tr>
<td><code v-pre>-&gt;wednesdays();</code></td>
<td>将任务限制在星期三</td>
</tr>
<tr>
<td><code v-pre>-&gt;thursdays();</code></td>
<td>将任务限制在星期四</td>
</tr>
<tr>
<td><code v-pre>-&gt;fridays();</code></td>
<td>将任务限制在星期五</td>
</tr>
<tr>
<td><code v-pre>-&gt;saturdays();</code></td>
<td>将任务限制在星期六</td>
</tr>
<tr>
<td><code v-pre>-&gt;between($start, $end);</code></td>
<td>限制任务运行在开始到结束时间范围内</td>
</tr>
<tr>
<td><code v-pre>-&gt;when(Closure);</code></td>
<td>根据闭包函数的返回来限制任务</td>
</tr>
</tbody>
</table>
<h4 id="时间范围限制" tabindex="-1"><a class="header-anchor" href="#时间范围限制"><span>时间范围限制</span></a></h4>
<p><code v-pre>between</code> 方法可以用来限制一天中某个时间范围内的任务执行：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'reminders:send'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">hourly</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">between</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'7:00'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'22:00'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>类似的，<code v-pre>unlessBetween</code> 方法可以用来在一段时间内排除任务的执行：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'reminders:send'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">hourly</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">unlessBetween</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'23:00'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'4:00'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="闭包测试限制" tabindex="-1"><a class="header-anchor" href="#闭包测试限制"><span>闭包测试限制</span></a></h4>
<p><code v-pre>when</code> 方法可以用来根据给定的测试的结果来限制任务的执行。换句话说，如果给定的 <code v-pre>Closure</code> 返回 <code v-pre>true</code>，那么只要没有其他约束条件阻止任务运行，任务就会执行：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'emails:send'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">when</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code v-pre>skip</code> 方法可以被看作是 <code v-pre>when</code> 的逆过程。如果 <code v-pre>skip</code> 方法返回 <code v-pre>true</code> 的话，那么任务将不会运行：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'emails:send'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">skip</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当链式调用多个 <code v-pre>when</code> 方法时，调度命令只有在所有的 <code v-pre>when</code> 条件返回 <code v-pre>true</code> 时才运行。</p>
<h3 id="避免任务重复" tabindex="-1"><a class="header-anchor" href="#避免任务重复"><span>避免任务重复</span></a></h3>
<p>默认情况，即便有相同的任务还在运行，调度内的任务依旧会被执行。为了避免这个问题，你可以使用 <code v-pre>withoutOverlapping</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'emails:send'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">withoutOverlapping</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>在上面这个例子中，如果没有其它 <a href="https://learnku.com/docs/laravel/5.5/artisan" target="_blank" rel="noopener noreferrer">Artisan 命令</a> <code v-pre>emails:send</code> 在运行的话，此任务将于每分钟被运行一次。如果你的任务在执行时间上有很大的不同，你无法准确预测给定任务需要多长时间，<code v-pre>withoutOverlapping</code> 方法将会特别有帮助。</p>
<h3 id="维护模式" tabindex="-1"><a class="header-anchor" href="#维护模式"><span>维护模式</span></a></h3>
<p>当 Laravel 处于 <a href="https://learnku.com/docs/laravel/5.5/configuration#maintenance-mode" target="_blank" rel="noopener noreferrer">维护模式</a> 时，Laravel 的调度功能将不会生效。这是因为我们不想让任务调度干扰你服务器上可能还未完成的项目。然而，如果你想强制某个任务在维护模式下运行的话，你可以使用 <code v-pre>evenInMaintenanceMode</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'emails:send'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">evenInMaintenanceMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="任务输出" tabindex="-1"><a class="header-anchor" href="#任务输出"><span>任务输出</span></a></h2>
<p>Laravel 调度器提供了几个方便的方法来处理调度任务生成的输出。首先，使用 <code v-pre>sendOutputTo</code> 方法可以将输出发送到单个文件上以便后续检查：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'emails:send'</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">sendOutputTo</span><span class="token punctuation">(</span><span class="token variable">$filePath</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果想将输出附加到指定的文件上，则可以使用 <code v-pre>appendOutputTo</code> 方法:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'emails:send'</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">appendOutputTo</span><span class="token punctuation">(</span><span class="token variable">$filePath</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>使用 <code v-pre>emailOutputTo</code> 方法，你可以通过电子邮件将输出发送到你所指定的邮箱上。在发送任务的输出之前，你应该先配置 Laravel 的 <a href="https://learnku.com/docs/laravel/5.5/mail" target="_blank" rel="noopener noreferrer">电子邮件服务</a>:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'foo'</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">sendOutputTo</span><span class="token punctuation">(</span><span class="token variable">$filePath</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">emailOutputTo</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'foo@example.com'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>{note} <code v-pre>emailOutputTo</code>、<code v-pre>sendOutputTo</code> 和 <code v-pre>appendOutputTo</code> 方法是 <code v-pre>command</code> 方法才有的，不支持在 <code v-pre>call</code> 方法上使用。</p>
</blockquote>
<h2 id="任务钩子" tabindex="-1"><a class="header-anchor" href="#任务钩子"><span>任务钩子</span></a></h2>
<p>通过 <code v-pre>before</code> 与 <code v-pre>after</code> 方法，你可以指定要在调度任务完成之前和之后执行的代码：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'emails:send'</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">before</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">         <span class="token comment">// 任务就要开始了…</span></span>
<span class="line">     <span class="token punctuation">}</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">after</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">         <span class="token comment">// 任务完成…</span></span>
<span class="line">     <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="ping-网址" tabindex="-1"><a class="header-anchor" href="#ping-网址"><span>Ping 网址</span></a></h4>
<p>使用 <code v-pre>pingBefore</code> 与 <code v-pre>thenPing</code> 方法，调度器可以在任务完成之前或之后自动 ping 给定的 URL。这个方法对于通知外部服务（例如 <a href="https://envoyer.io/" target="_blank" rel="noopener noreferrer">Laravel Envoyer</a>）你的调度任务正在开始或已经完成执行很有用：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'emails:send'</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">daily</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">pingBefore</span><span class="token punctuation">(</span><span class="token variable">$url</span><span class="token punctuation">)</span></span>
<span class="line">     <span class="token operator">-></span><span class="token function">thenPing</span><span class="token punctuation">(</span><span class="token variable">$url</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>无论是使用 <code v-pre>pingBefore($url)</code> 还是 <code v-pre>thenPing($url)</code> 的功能，都需要 Guzzle HTTP 函数库的支持。你可以使用 <code v-pre>Composer</code> 将 Guzzle 函数库添加到你的项目中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">composer <span class="token keyword">require</span> guzzlehttp<span class="token operator">/</span>guzzle</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="译者署名" tabindex="-1"><a class="header-anchor" href="#译者署名"><span>译者署名</span></a></h2>
<table>
<thead>
<tr>
<th>用户名</th>
<th>头像</th>
<th>职能</th>
<th>签名</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://learnku.com/users/13655" target="_blank" rel="noopener noreferrer">@沈益飞</a></td>
<td><img src="https://cdn.learnku.com/uploads/avatars/13655_1490162781.png?imageView2/1/w/100/h/100" alt="100"></td>
<td>翻译</td>
<td><a href="https://github.com/m809745357" target="_blank" rel="noopener noreferrer">@m809745357</a> at Github</td>
</tr>
<tr>
<td><a href="https://learnku.com/users/5350" target="_blank" rel="noopener noreferrer">@JokerLinly</a></td>
<td><img src="https://cdn.learnku.com/uploads/avatars/5350_1481857380.jpg" alt="5350_1481857380.jpg"></td>
<td>Review</td>
<td>Stay Hungry. Stay Foolish.</td>
</tr>
</tbody>
</table>
<hr>
<blockquote>
<p>{note} 欢迎任何形式的转载，但请务必注明出处，尊重他人劳动共创开源社区。</p>
<p>转载请注明：本文档由 Laravel China 社区 <a href="https://laravel-china.org/" target="_blank" rel="noopener noreferrer">laravel-china.org</a> 组织翻译，详见 <a href="https://learnku.com/laravel/t/5756/laravel-55-document-translation-call-come-and-join-the-translation" target="_blank" rel="noopener noreferrer">翻译召集帖</a>。</p>
<p>文档永久地址： <a href="https://learnku.com/docs/laravel" target="_blank" rel="noopener noreferrer">《Laravel 中文文档》</a></p>
</blockquote>
</div></template>


